package com.yuyou.tas.gateway.filter;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.util.WebUtils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.yuyou.tas.util.bean.LoginRedisObj;
import com.yuyou.tas.util.bean.ReturnCode;
import com.yuyou.tas.util.bean.ReturnResult;
import com.yuyou.tas.util.config.SystemConfig;

public class AccessFilter extends ZuulFilter{
	
	@Value("${denfind.swagger}")
	private  boolean swagger;
	
	private static  List<String> exclusiveList=new ArrayList<String>();
				
	static {		
		exclusiveList.add("login");
		exclusiveList.add("api-docs");
		exclusiveList.add("Captcha");
		exclusiveList.add("swagger");	
		exclusiveList.add("upgradeDate");	
		exclusiveList.add("health");			
		exclusiveList.add("terminal");		
	}
	
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	private boolean isVer=false;
	
	
	@Override
	public Object run() {
		if(isVer){
			 return null;
		}
		RequestContext ctx = RequestContext.getCurrentContext() ;
		HttpServletRequest request = ctx.getRequest() ;

        String accessToken = request.getHeader("accessToken");
        if(StringUtils.isEmpty(accessToken)){
        	accessToken = request.getParameter("accessToken") ;
        }
        if(StringUtils.isEmpty(accessToken)){
			// 检测是否为上传请求
			String contentType = request.getContentType();
			if (contentType != null && contentType.toLowerCase().startsWith("multipart/"))
			{
				MultipartHttpServletRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);
				accessToken = multipartRequest.getParameter("accessToken");
			}
		}

        if (StringUtils.isEmpty(accessToken)) {
        	ctx.setSendZuulResponse(false);// 过滤该请求，不对其进行路由  
        	ctx.setResponseStatusCode(200);// 返回错误码
        	ReturnResult<String> res=new ReturnResult<String>(false,ReturnCode.code._3001.getMessage(),null,ReturnCode.code._3001.getCode(),ReturnCode.code._3001.getMessage());
        	ctx.setResponseBody(res.toJsonString());// 返回错误内容 
        	ctx.getResponse().setContentType("text/html;charset=UTF-8");  
        	ctx.set("isSuccess", false);
        	return null;  
        }
        String jsonObj=stringRedisTemplate.opsForValue().get(accessToken);
        if(StringUtils.isEmpty(jsonObj)){
        	ctx.setSendZuulResponse(false);// 过滤该请求，不对其进行路由  
        	ctx.setResponseStatusCode(200);// 返回错误码
        	ReturnResult<String> res=new ReturnResult<String>(false,ReturnCode.code._3001.getMessage(),null,ReturnCode.code._3001.getCode(),ReturnCode.code._3001.getMessage());
        	ctx.setResponseBody(res.toJsonString());// 返回错误内容 
        	ctx.getResponse().setContentType("text/html;charset=UTF-8");  
        	ctx.set("isSuccess", false);
        	return null; 
        } 
        
        //权限
        String uri=request.getRequestURI();
        LoginRedisObj obj=JSONObject.parseObject(jsonObj, new TypeReference<LoginRedisObj>() {});
        Long pageCount=obj.getPageUrlSet().stream().filter(pageUrl -> uri.contains(pageUrl)).count();
        if(pageCount==0){
        	ctx.setSendZuulResponse(false);// 过滤该请求，不对其进行路由  
        	ctx.setResponseStatusCode(200);// 返回错误码
        	ReturnResult<String> res=new ReturnResult<String>(false,ReturnCode.code._3003.getMessage(),null,ReturnCode.code._3003.getCode(),ReturnCode.code._3003.getMessage());
        	ctx.setResponseBody(res.toJsonString());// 返回错误内容 
        	ctx.getResponse().setContentType("text/html;charset=UTF-8");  
        	ctx.set("isSuccess", false);
        	return null;
        }
        
        //延长token
        stringRedisTemplate.expire(accessToken, SystemConfig.REDIS_EXPIRE_TIME,SystemConfig.REDIS_EXPIRE_TIME_UNIT);      
        stringRedisTemplate.expire(String.valueOf(obj.getUserId()), SystemConfig.REDIS_EXPIRE_TIME,SystemConfig.REDIS_EXPIRE_TIME_UNIT);
        // 设值，让下一个Filter看到下一个Filter的状态  
        ctx.set("isSuccess", true);
        return null;	
	}
	
	@Override
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext() ;
		HttpServletRequest request = ctx.getRequest() ;
		String uri=request.getRequestURI();
		//登录绕过拦截器
		if(!swagger && uri.contains("swagger")){
			return true;
		}
		for(String exUri:exclusiveList){
			if(uri.contains(exUri)){
	            return false;
			}
		}		
		return true;
	}

	@Override
	public int filterOrder() {
		return 0;
	}

	@Override
	public String filterType() {
		 return "pre";
	}

}
